package com.xtaller.easy.admin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.common.convert.*;
import com.xtaller.easy.admin.base.TServiceImpl;
import com.xtaller.easy.admin.config.Constant;
import com.xtaller.easy.admin.mapper.SysLabelMapper;
import com.xtaller.easy.admin.model.SysLabel;
import com.xtaller.easy.admin.service.ISysLabelService;
import com.xtaller.easy.admin.tps.CacheKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import com.xtaller.common.bean.Where;
/**
 * Created by Taller on 2018/04/13
 */
@Service
public class SysLabelService extends TServiceImpl<SysLabelMapper,SysLabel> implements ISysLabelService {
    @Autowired
    private CacheKit cacheKit;
    @Autowired
    private SysDictService dictService;

    /**************************CURD begin******************************/
    // 创建
    @Override
    public SysLabel createSysLabel(SysLabel model) {
        if(!this.insert(model))
            return null;
        try{
            RefreshSysLabelCache();
        }catch (Exception e){}
        return this.selectById(model.getId());
    }

    // 删除
    @Override
    public Boolean deleteSysLabel(Object ids,String reviser) {
        if(!this.delete(ids,reviser))
            return false;
        try{
            RefreshSysLabelCache();
        }catch (Exception e){}
        return true;
    }

    // 修改
    @Override
    public SysLabel updateSysLabel(SysLabel model) {
        if(!this.update(model))
            return null;
        try{
            RefreshSysLabelCache();
        }catch (Exception e){}
        return this.selectById(model.getId());
    }

    // 查询
    @Override
    public List<SysLabel> findByIds(Object ids) {
        return this.selectByIds(ids);
    }

    // 属于
    @Override
    public Boolean exist(List<Where> w) {
        w.add(new Where("1"));
        return this.query(w).size() > 0;
    }

    // 查询一个id是否存在
    @Override
    public Boolean existId(Object id) {
        where = W.f(
                W.and("id","eq",id),
                W.field("1")
        );
        return this.query(where).size() > 0;
    }

    /**************************CURD end********************************/
    @Override
    public Boolean existCode(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("moduleId", "eq", 0),
                    W.and("id", "ne", model.getId())
            );
        }else{
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("moduleId", "eq", 0)
            );
        }
        return this.queryOne(where) == null ? false : true;
    }
    @Override
    public Boolean existGroupCode(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("moduleId", "eq", model.getModuleId()),
                    W.and("parentId", "eq", model.getModuleId()),
                    W.and("id", "ne", model.getId())
            );
        }else{
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("moduleId", "eq", model.getModuleId()),
                    W.and("parentId", "eq", model.getModuleId())
            );
        }
        return this.queryOne(where) == null ? false : true;
    }
    @Override
    public Boolean existLabelCode(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("parentId", "eq", model.getParentId()),
                    W.and("id", "ne", model.getId())
            );
        }else{
            where = W.f(
                    W.and("code", "eq", model.getCode()),
                    W.and("parentId", "eq", model.getParentId())
            );
        }
        return this.queryOne(where) == null ? false : true;
    }

    @Override
    public Boolean existModule(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("id", "ne", model.getId()),
                    W.and("moduleId", "eq", 0)
            );
        }else{
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("moduleId", "eq", 0)
            );
        }
        return this.queryOne(where) == null ? false : true;
    }
    @Override
    public Boolean existGroup(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("id", "ne", model.getId()),
                    W.and("parentId", "eq", model.getModuleId()),
                    W.and("moduleId", "eq", model.getModuleId())
            );
        }else{
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("parentId", "eq", model.getModuleId()),
                    W.and("moduleId", "eq", model.getModuleId())
            );
        }
        return this.queryOne(where) == null ? false : true;
    }
    @Override
    public Boolean existName(SysLabel model, boolean isCreate) {
        if(!isCreate){
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("id", "ne", model.getId()),
                    W.and("parentId", "eq", model.getParentId())
            );
        }else{
            where = W.f(
                    W.and("name", "eq", model.getName()),
                    W.and("parentId", "eq", model.getParentId())
            );
        }
        return this.queryOne(where) == null ? false : true;
    }
    @Override
    public List<SysLabel> getModule() {
        where = W.f(
                W.and("moduleId", "eq", 0),
                W.field("id", "name", "code", "sort", "remark"),
                W.order("sort", "asc")
        );
        return this.query(where);
    }
    @Override
    public List<SysLabel> getByModuleId(Long moduleId) {
        where = W.f(
                W.and("moduleId", "eq", moduleId),
                W.and("parentId", "eq", moduleId),
                W.field("id", "name", "code", "sort", "parentId", "remark", "type"),
                W.order("sort", "asc")
        );
        return this.query(where);
    }
    @Override
    public List<SysLabel> getByParentId(String parentId) {
        where = W.f(
                W.and("parentId", "eq", parentId),
                W.field("id", "name", "code", "sort", "parentId", "remark", "type"),
                W.order("sort", "asc")
        );
        return this.query(where);
    }
    @Override
    public List<SysLabel> getByModuleIdAndParentId(Long moduleId, String parentId) {
        where = W.f(
                W.and("parentId", "eq", parentId),
                W.and("moduleId", "eq", moduleId),
                W.field("id", "name", "code", "sort", "parentId", "remark", "type"),
                W.order("sort", "asc")
        );
        return this.query(where);
    }

    @Override
    public List<SysLabel> getByModuleIdOrParentId(String id) {
        return baseMapper.getByModuleIdOrParentId(id);
    }

    @Override
    public List<JSONObject> getTreeLabel() {
        List<JSONObject> list = cacheKit.getList(Constant.CACHE_SYS_LABEL);
//        if(list != null)
//            return list;
        return RefreshSysLabelCache();
    }
    @Override
    public List<JSONObject> RefreshSysLabelCache(){
        List<JSONObject> list = F.f2l(baseMapper.getTreeLabel(),
                "id", "moduleId", "parentId");
        // 数据处理
        if(list.size() > 0){
            list = formatDict(list);
            Object o = L.list2Tree(list, "0");
            list = J.o2l(o);
        }
        cacheKit.setVal(Constant.CACHE_SYS_LABEL, list);
        return list;
    }

    @Override
    public JSONObject getLabelByCode(String code) {
        String item[] = code.split("@");
        List<JSONObject> label = getTreeLabel();
        //
        JSONObject data = new JSONObject();
        if(label.size() > 0){
            switch (item.length){
                case 1:
                    data = getByCode(label, item[0]);
                    break;
                case 2:
                    data = getByCode(label, item[0]);
                    data = getByCode(J.o2l(data.get("children")), item[1]);
                    break;
            }
            return data;
        }else {
            return new JSONObject();
        }
    }

    private JSONObject getByCode(List<JSONObject> list, String code){
        JSONObject data = new JSONObject();
        if(list.size() > 0) {
            for (JSONObject object : list) {
                if (V.isEqual(object.getString("code"), code)) {
                    data = object;
                    break;
                }
            }
        }
        return data;
    }

    // 处理标签中的字典信息
    private List<JSONObject> formatDict(List<JSONObject> labels){
        // 拿出type=9的数据
        List<JSONObject> tem = new ArrayList<>();
        for(JSONObject label:labels){
            if(label.getInteger("type") == 9){
                tem.add(label);
            }
        }
        // 取出标签的code值
        if(tem.size() > 0){
            String[] item = L.getAttrs2Arr(tem, "code");
            item = L.removeRepeat(item);
            List<JSONObject> dicts = dictService.getInByCode(item);
            if(dicts.size() > 0){
                for(JSONObject label:labels){
                    if(label.getInteger("type") == 9){
                        List<JSONObject> dictList = new ArrayList<>();
                        for(JSONObject dict:dicts){
                            if(V.isEqual(dict.getString("dict"), label.getString("code"))){
                                JSONObject object = new JSONObject();
                                object.put("txt", dict.getString("txt"));
                                object.put("val", dict.getString("val"));
                                dictList.add(object);
                            }
                        }
                        label.put("options", dictList);
                    }
                }
            }
        }
        return labels;
    }
}